MediaLiveのPull型Inputでアクセス元はどこになるのかをHLS Input typeで確認してみた

MediaLiveのPull型Inputでアクセス元はどこになるのかをHLS Input typeで確認してみた

Pull型InputはどんなIPアドレスでSourceにアクセスするのか、HLS Input typeで確認してみました。ChannelのEgress用IPアドレスでアクセスし、Inputが紐づくChannelによってIPアドレスが変わりました。
Clock Icon2024.07.31

はじめに

清水です。先日MediaLive SRT caller input typeの動作検証を行っている際、対になるSRT listener側でアクセス元となるMediaLive InputのIPアドレスは確認できるのか、ということが気になりました。

MediaLive Inputを例えばRTMP (push)などPush型で利用する場合は、そのInputリソースに対してIPアドレスがEndpointとして払い出されます。これを宛先にStreaming Softwareなどから映像を入力するかたちですね。Input作成時にSource情報が不要な点も特徴です。

pi06

pi07

対してPull型のInput typeでは、リソース作成時にSource情報が必要となります。以下はSRT caller input typeの例です。MediaLive Input側から入力元に接続するため、リソース作成時にその接続先を設定する必要があるわけですね。

pi08

なお、Input typeのPush or PullについてはUser Guideの以下ページにまとめられています。

Pull型のInput typeでは、Inputリソース作成後にIPアドレスが払い出されるということはありません。 それでは、MediaLiveではどういったIPアドレス、接続元から入力元となるSouceに接続しているのでしょうか?

MediaLive User Guideを確認した限りでは特に明記されていないようだったので、動作検証を行い確認してみることにしました。なお、確認対象としてはHLS input typeを選択しました。接続元IPアドレスなどの情報をログとして確認しやすいものは何かと考えたとき、nginx-rtmp-moduleを使いHLSライブストリーミングを行う映像ソースを準備、nginx側のアクセスログを参照するのがやりやすいかな、と思ったわけです。

以下、動作検証の内容についてまとめていきます。まずはHLS入力ソースとしてnginx on EC2環境下でnginx-rtmp-moduleを使いHLSライブストリーミングができる環境を準備します。ついでMediaLiveのHLS input typeでリソースを準備、MediaLiveのChannelをStartして動画配信をしながらnginx側のアクセスログでMediaLive Pull型Inputのアクセス元がどうなっているかを確認しました。

検証結果について先にまとめておくと、MediaLive ChannelのEgress endpointsのSouce IPからHLS Source URLにアクセスしていることが確認できました。

HLS入力ソースの準備

まずはMediaLiveのPull型Inputで利用できるHLS入力ソースを準備します。アクセスログでアクセス元IPアドレスが容易に確認できることが望ましいので、nginx on EC2環境を準備、nginx-rtmp-moduleでHLSライブ動画配信ができる環境を準備しました。

以下、EC2のOSやnginxなどのバージョンは少し古いものとなります。以前検証した際の記録をベースに環境を準備したためです。現状ではOSについてもAmazon Linux 2ではなくAmazon Linux 2023、nginxについてもより新しいバージョンが利用可能かと思いますので、そちらを利用するようにしてください。

EC2インスタンスの準備

今回は以下のEC2インスタンスを準備しました。

  • AMIはAmazon Linux 2 Kernel 5.10 AMI 2.0.20240719.0 x86_64 HVM gp2
  • インスタンスタイプはt2.micro
  • パブリックサブネットに配置
  • Security Groupで以下ポートを適切に快方
    • SSH(22)、HTTP(80)、RTMP(1935)
  • EBSは8GiB, gp3 (3,000 IOPS, スループット125)

nginxとnginx-rtmp-moduleのビルドとインストール

まずは事前にビルドの際に必要となりそうなモジュールをyumでインストールしておきます。

$ sudo yum install -y gcc pcre-devel zlib-devel openssl openssl-devel libxml2-devel libxslt-devel

作業ディレクトリに移動して、nginxのソースコードとnginx-rtmp-moduleのコードをダウンロード、展開しておきます。今回は作業ディレクトリを /home/ec2-user/build/nginx としました。(なお先述の通り、今回使用しているnginx、nginx-rtmp-moduleは最新版ではありません。ご注意ください。)

$ mkdir -p /home/ec2-user/build/nginx
$ cd /home/ec2-user/build/nginx
$ wget https://nginx.org/download/nginx-1.20.0.tar.gz
$ wget https://github.com/arut/nginx-rtmp-module/archive/afd350e0d8b7820d7d2cfc3fa748217153265ce6.tar.gz
$ tar xvf nginx-1.20.0.tar.gz
$ tar xvf afd350e0d8b7820d7d2cfc3fa748217153265ce6.tar.gz

nginx-1.20.0ディレクトリに移動、 --add-module でnginx-rtmp-moduleを指定してconfigureを実行します。

$ cd nginx-1.20.0/
$ ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-afd350e0d8b7820d7d2cfc3fa748217153265ce6 2>&1 | tee log_configure.log

最後に表示されるConfiguration summaryはメモしておきます。

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

続いてmake & make installします。

$ make 2>&1 | tee log_make.log
$ sudo make install 2>&1 | tee log_make_install.log

エラーなどなく終了したことを確認し、Configuration summaryに記載があったnginx path prefix /usr/local/nginx/をlsしてみます。以下4つのディレクトリが確認できますね。

$ ls /usr/local/nginx/
conf  html  logs  sbi

nginx公開用ディレクトリの作成

nginxで公開するディレクトリを作成、権限を編集しておきます。

$ sudo mkdir -p /var/www/hls
$ sudo chmod 777 /var/www/hls
$ ls -l /var/www/
合計 0
drwxrwxrwx 2 root root 6  731 02:03 hls

nginxの設定(nginx.confの編集)

続いてnginxの設定ファイル( /usr/local/nginx/conf/nginx.conf ) を編集します。なお、筆者は愛用しているEmacsを編集用エディタとして使用したかったため、このタイミングでsudo yum install -y emacsを実行してEmacsをインストールしました。

お好みのエディタで/usr/local/nginx/conf/nginx.confを開き、以下内容を記載します。(なお、以下nginx.confの設定内容についてはインターネット上の各種情報を参考に作成しました。例えばこちらなどです。参考文献として関連リンクなどについてすべてまとめることができればよかったのですが、詳細に記録していなかったことから一例のみの紹介とさせていただきます。)

$ sudo emacs /usr/local/nginx/conf/nginx.conf
nginx.conf
worker_processes  1;
error_log  logs/error.log error;

events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1935;
        access_log logs/rtmp_access.log;
        chunk_size 4096;

        application app {
            live on;
            record off;
            allow publish all;  # RTMP pushを許可
            deny play all;  # RTMP pullを禁止

            # HLS配信用ファイルを保存
            hls on;
            hls_type event;
            hls_path /var/www/hls/;
            hls_fragment 6;
            hls_playlist_length 60;
        }
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/http_access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root /var/www/;
            index  index.html index.htm;

            # Disable cache
            add_header 'Cache-Control' 'no-cache';

            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length';

            # allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }

            types {
                application/dash+xml mpd;
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }

        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

nginx.confを編集後、設定ファイルに問題がないかも確認しておきましょう。

$ sudo /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

nginxの起動と映像の打ち上げ

nginx.confに問題ないことが確認できたら、niginxを起動します。

$ sudo /usr/local/nginx/sbin/nginx

起動後、Streaming Softwareから映像を打ち上げます。OBS Stuidoを使用しました。「設定」>「配信」の項目を開き、サーバでrtmp://[EC2のIPアドレス]/appを、ストリームキーで任意の文字列(今回はinstとしました)を入力します。

pi09

OBS Studioから映像を打ち上げ、HLS対応動画プレイヤーで映像が視聴できるか確認しておきます。視聴用のアドレス(m3u8エンドポイント)はhttp://[EC2のIPアドレス]/hls/[ストリームキー].m3u8となります。

今回はmacOSのSafariブラウザで視聴を確認しました。hls.js demoなどのJavaScriptを利用した動画プレイヤーの場合、HTTPSではないといった制限などから再生できない場合がありますので注意しましょう。

pi02

以上でHLS入力ソースの準備が完了です。

MediaLiveリソース準備

続いて動作検証用のMediaLiveリソースについて準備してきます。

HLS typeなInputの作成

まずはHLS typeなInputを作成します。MediaLiveのマネジメントコンソールのInputs画面、[Create input]ボタンから進みます。Input nameを適切に入力し、Input typeでHLSを選択します。Input classはSINGLE_INPUTとしました。Input source AのURLに映像ソースとなるHLS入力ソースのm3u8エンドポイント(http://[EC2のIPアドレス]/hls/[ストリームキー].m3u8)を入力します。

pi03

pi04

HLS typeなInputが作成できました!入力元となる映像ソース、HLSエンドポイントのURLは設定したものが記載されていますが、MediaLive側のIPアドレスの情報はありませんね。

pi05

そのほかMediaLiveリソースの作成

続いてChannelなど、そのほかMediaLive関連のリソースを作成していきます。作成にはMediaLive Workflow Wizardを使用しました。以下ブログエントリと同様の手順、Workflow WizardでInput typeをRTMP (push)としていちどリソース全体を作成し、リソース作成後にChannelに紐づいているInputリソースをHLS typeなものに付け替える、という方法を採りました。

手順の詳細については省略させていただきます。上記ブログエントリを参照ください。

以下、ポイントになる箇所です。Workflow作成後、MediaLive Channelで[Edit Channel]して設定内容を変更します。Input Attachmentを一度削除([Remove])して先ほど作成したHLS typeなInputをAttachし直しますが、[Confirm]ボタンの押下を忘れなようにしましょう。(筆者は何度か忘れたことがあります……)その後[Update channel]します。

pi10

ライブストリーミングを実施しnginxアクセスログを確認

各リソースの準備ができました。実際の動作検証である、MediaLive Inputはどのようなアクセス元(IPアドレス)でSourceに接続しているのかを確認していきましょう。OBS Studioからnginx on EC2に向けて映像を打ち上げ、またMediaLive ChannelをStartさせます。Workflow Wizardで作成したMediaPackage HLS endpointのPreview playerで問題なく映像の視聴ができていることを確認しつつ、nginxのアクセスログ(/usr/local/nginx/logs/http_access.log)を参照してみましょう。

以下のアクセスログが記録されていました。

/usr/local/nginx/logs/http_access.log
52.XX.X.236 - - [31/Jul/2024:08:05:24 +0000] "GET /hls/inst.m3u8 HTTP/1.1" 200 354 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:25 +0000] "GET /hls/inst-11.ts HTTP/1.1" 206 2864180 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:25 +0000] "GET /hls/inst-10.ts HTTP/1.1" 206 2864368 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:25 +0000] "GET /hls/inst-7.ts HTTP/1.1" 200 41992 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:32 +0000] "GET /hls/inst.m3u8 HTTP/1.1" 200 355 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:33 +0000] "GET /hls/inst-12.ts HTTP/1.1" 206 2866060 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:33 +0000] "GET /hls/inst-8.ts HTTP/1.1" 200 41992 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:40 +0000] "GET /hls/inst.m3u8 HTTP/1.1" 200 356 "-" "AWSElementalMediaLive" "-"
52.XX.X.236 - - [31/Jul/2024:08:05:41 +0000] "GET /hls/inst-13.ts HTTP/1.1" 206 2865684 "-" "AWSElementalMediaLive" "-"

MediaLive Inputからは52.XX.X.236というIPアドレスでアクセスしていることが確認できますね。またUser AgentはAWSElementalMediaLiveのようです。(そのままではありますが。)

さてこの52.XX.X.236というIPアドレスについて確認してみましょう。どこでもないところから突如現れたIPアドレス、というわけではなく、MediaLive ChannelのEgress endpointsのSource IPがこのIPアドレスとなっていました。

pi11

このEgerss endpointsのSource IPについては、MediaLiveからの出力の際に使用するIPアドレスである、という認識です。MediaLive User Guideにも以下のように記載されています。(逆い言えば、確認した限りではこれ以上の情報はUser Guideに記載されていませんでした。)

Egress endpoints – This pane shows one line for each pipeline. The Source IP is the channel endpoint for this pipeline. The channel endpoint is the egress from the pipeline. From this point, the content goes to the output destinations for each of the output groups in the channel.

Push型のInputでは上記ChannelのEgress endpoints source ip以外にIPアドレスが割り振られていたことから、個人的にはPull型の場合でもChannelとは別のIPアドレスが割り振られる、あくまでChannelとInputのIPアドレスは別だと予想していたのですが。Channelの(しかもEgress用の)IPアドレスを使ってInputのHLS Source URLにアクセスしている、という結果になりました。

Inputのアタッチ元Channelを変更してアクセス元を確認

ちょっと意外な?結果に驚きつつも、もう一つ動作検証パターンを確認してみます。InputについてはChannelから取り外しができ、別のChannelにアタッチし直すことができますよね。先ほど作成したHLS typeなInputを、確認したものとは別のChannelに付け替えます。この場合、HLS Source URLにはアタッチし直されたChannelのEgress endpoints source ipが使われるのでしょうか。

付け替え先となるChannelリソースは先ほどと同様、Workflow wizardで作成します。作成したChannelに対して、HLS typeなInputをアタッチします。あらかじめ1つ目のChannelからHLS typeなInputはデタッチしておきましょう。

pi12

pi13

先ほどと同様にライブストリーミングを実施、映像が問題なく視聴できていることを確認しつつ、nginxのアクセスログを参照してみます。

以下のアクセスログが記録されていました。MediaLive Inputからは18.XXX.XX.202というIPアドレスでアクセスしていますね。

/usr/local/nginx/logs/http_access.log
18.XXX.XX.202 - - [31/Jul/2024:08:13:48 +0000] "GET /hls/inst-68.ts HTTP/1.1" 200 97016 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:13:52 +0000] "GET /hls/inst-69.ts HTTP/1.1" 200 41992 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:13:52 +0000] "GET /hls/inst.m3u8 HTTP/1.1" 200 362 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:13:56 +0000] "GET /hls/inst.m3u8 HTTP/1.1" 200 362 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:14:00 +0000] "GET /hls/inst-73.ts HTTP/1.1" 206 2864368 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:14:00 +0000] "GET /hls/inst-70.ts HTTP/1.1" 200 41992 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:14:05 +0000] "GET /hls/inst.m3u8 HTTP/1.1" 200 362 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:14:08 +0000] "GET /hls/inst-74.ts HTTP/1.1" 206 2866812 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:14:08 +0000] "GET /hls/inst-71.ts HTTP/1.1" 200 97016 "-" "AWSElementalMediaLive" "-"
18.XXX.XX.202 - - [31/Jul/2024:08:14:13 +0000] "GET /hls/inst.m3u8 HTTP/1.1" 200 362 "-" "AWSElementalMediaLive" "-"

HLS typeなInputをアタッチしているChannelのDestinationsタブ、Egress endpointsの項目を確認してみるとSource IPがこの18.XXX.XX.202となっていました。

pi14

HLS typeなInputの場合、Egress endpointsのSource IPを使用してHLS Source URLにアクセスしており、アタッチされるChannelが変わればアクセス元IPアドレスも変わる、という結果になりました。

まとめ

MediaLiveのSRT caller inpu typeの動作検証を行っているときに気になった、Pull型のMediaLive Inputのアクセス元はどこになるか、という点について動作検証を行い確認してみました。Pull型のInput typeの1つであるHLSを使用した場合、MediaLive ChannelのEgress endpointsのSource IPを使ってHLS Source URLにアクセスしていました。

Push型のInput typeではChannelとは別のIPアドレスが割り振られることから、Pull型でも(明記はされなくとも)Channelとは別のIPアドレスでのアクセスになるのではと個人的には予想していましたが、異なる結果となりましたね。InputないしChannel classをSINGLEではなくSTANDARDにした場合やInput failover機能を利用した場合、そして手段があればSRT callerRTMP (pull)などほかのPull型についても別途確認できればなと思います。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.